home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 365_02 / move2.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  6KB  |  292 lines

  1. /* move2.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    14407 SW Teal Blvd. #C
  6.  *    Beaverton, OR 97005
  7.  *    kirkenda@cs.pdx.edu
  8.  */
  9.  
  10.  
  11. /* This function contains the movement functions that perform RE searching */
  12.  
  13. #include "config.h"
  14. #include "vi.h"
  15. #include "regexp.h"
  16.  
  17. extern long    atol();
  18.  
  19. static regexp    *re;    /* compiled version of the pattern to search for */
  20. static        prevsf;    /* boolean: previous search direction was forward? */
  21.  
  22. #ifndef NO_EXTENSIONS
  23. /*ARGSUSED*/
  24. MARK m_wsrch(word, m, cnt)
  25.     char    *word;    /* the word to search for */
  26.     MARK    m;    /* the starting point */
  27.     int    cnt;    /* ignored */
  28. {
  29.     char    buffer[30];
  30.  
  31.     /* wrap \< and \> around the word */
  32.     strcpy(buffer, "/\\<");
  33.     strcat(buffer, word);
  34.     strcat(buffer, "\\>");
  35.  
  36.     /* show the searched-for word on the bottom line */
  37.     move(LINES - 1, 0);
  38.     qaddstr(buffer);
  39.     clrtoeol();
  40.     refresh();
  41.  
  42.     /* search for the word */
  43.     return m_fsrch(m, buffer);
  44. }
  45. #endif
  46.  
  47. MARK    m_nsrch(m)
  48.     MARK    m;    /* where to start searching */
  49. {
  50.     if (prevsf)
  51.     {
  52.         m = m_fsrch(m, (char *)0);
  53.         prevsf = TRUE;
  54.     }
  55.     else
  56.     {
  57.         m = m_bsrch(m, (char *)0);
  58.         prevsf = FALSE;
  59.     }
  60.     return m;
  61. }
  62.  
  63. MARK    m_Nsrch(m)
  64.     MARK    m;    /* where to start searching */
  65. {
  66.     if (prevsf)
  67.     {
  68.         m = m_bsrch(m, (char *)0);
  69.         prevsf = TRUE;
  70.     }
  71.     else
  72.     {
  73.         m = m_fsrch(m, (char *)0);
  74.         prevsf = FALSE;
  75.     }
  76.     return m;
  77. }
  78.  
  79. MARK    m_fsrch(m, ptrn)
  80.     MARK    m;    /* where to start searching */
  81.     char    *ptrn;    /* pattern to search for */
  82. {
  83.     long    l;    /* line# of line to be searched */
  84.     char    *line;    /* text of line to be searched */
  85.     int    wrapped;/* boolean: has our search wrapped yet? */
  86.     int    pos;    /* where we are in the line */
  87. #ifndef CRUNCH
  88.     long    delta = INFINITY;/* line offset, for things like "/foo/+1" */
  89. #endif
  90.  
  91.     /* remember: "previous search was forward" */
  92.     prevsf = TRUE;
  93.  
  94.     if (ptrn && *ptrn)
  95.     {
  96.         /* locate the closing '/', if any */
  97.         line = parseptrn(ptrn);
  98. #ifndef CRUNCH
  99.         if (*line)
  100.         {
  101.             delta = atol(line);
  102.         }
  103. #endif
  104.         ptrn++;
  105.  
  106.         /* free the previous pattern */
  107.         if (re) free(re);
  108.  
  109.         /* compile the pattern */
  110.         re = regcomp(ptrn);
  111.         if (!re)
  112.         {
  113.             return MARK_UNSET;
  114.         }
  115.     }
  116.     else if (!re)
  117.     {
  118.         msg("No previous expression");
  119.         return MARK_UNSET;
  120.     }
  121.  
  122.     /* search forward for the pattern */
  123.     pos = markidx(m) + 1;
  124.     pfetch(markline(m));
  125.     if (pos >= plen)
  126.     {
  127.         pos = 0;
  128.         m = (m | (BLKSIZE - 1)) + 1;
  129.     }
  130.     wrapped = FALSE;
  131.     for (l = markline(m); l != markline(m) + 1 || !wrapped; l++)
  132.     {
  133.         /* wrap search */
  134.         if (l > nlines)
  135.         {
  136.             /* if we wrapped once already, then the search failed */
  137.             if (wrapped)
  138.             {
  139.                 break;
  140.             }
  141.  
  142.             /* else maybe we should wrap now? */
  143.             if (*o_wrapscan)
  144.             {
  145.                 l = 0;
  146.                 wrapped = TRUE;
  147.                 continue;
  148.             }
  149.             else
  150.             {
  151.                 break;
  152.             }
  153.         }
  154.  
  155.         /* get this line */
  156.         line = fetchline(l);
  157.  
  158.         /* check this line */
  159.         if (regexec(re, &line[pos], (pos == 0)))
  160.         {
  161.             /* match! */
  162.             if (wrapped && *o_warn)
  163.                 msg("(wrapped)");
  164. #ifndef CRUNCH
  165.             if (delta != INFINITY)
  166.             {
  167.                 l += delta;
  168.                 if (l < 1 || l > nlines)
  169.                 {
  170.                     msg("search offset too big");
  171.                     return MARK_UNSET;
  172.                 }
  173.                 force_flags = LNMD|INCL;
  174.                 return MARK_AT_LINE(l);
  175.             }
  176. #endif
  177.             return MARK_AT_LINE(l) + (int)(re->startp[0] - line);
  178.         }
  179.         pos = 0;
  180.     }
  181.  
  182.     /* not found */
  183.     msg(*o_wrapscan ? "Not found" : "Hit bottom without finding RE");
  184.     return MARK_UNSET;
  185. }
  186.  
  187. MARK    m_bsrch(m, ptrn)
  188.     MARK    m;    /* where to start searching */
  189.     char    *ptrn;    /* pattern to search for */
  190. {
  191.     long    l;    /* line# of line to be searched */
  192.     char    *line;    /* text of line to be searched */
  193.     int    wrapped;/* boolean: has our search wrapped yet? */
  194.     int    pos;    /* last acceptable idx for a match on this line */
  195.     int    last;    /* remembered idx of the last acceptable match on this line */
  196.     int    try;    /* an idx at which we strat searching for another match */
  197. #ifndef CRUNCH
  198.     long    delta = INFINITY;/* line offset, for things like "/foo/+1" */
  199. #endif
  200.  
  201.     /* remember: "previous search was not forward" */
  202.     prevsf = FALSE;
  203.  
  204.     if (ptrn && *ptrn)
  205.     {
  206.         /* locate the closing '?', if any */
  207.         line = parseptrn(ptrn);
  208. #ifndef CRUNCH
  209.         if (*line)
  210.         {
  211.             delta = atol(line);
  212.         }
  213. #endif
  214.         ptrn++;
  215.  
  216.         /* free the previous pattern, if any */
  217.         if (re) free(re);
  218.  
  219.         /* compile the pattern */
  220.         re = regcomp(ptrn);
  221.         if (!re)
  222.         {
  223.             return MARK_UNSET;
  224.         }
  225.     }
  226.     else if (!re)
  227.     {
  228.         msg("No previous expression");
  229.         return MARK_UNSET;
  230.     }
  231.  
  232.     /* search backward for the pattern */
  233.     pos = markidx(m);
  234.     wrapped = FALSE;
  235.     for (l = markline(m); l != markline(m) - 1 || !wrapped; l--)
  236.     {
  237.         /* wrap search */
  238.         if (l < 1)
  239.         {
  240.             if (*o_wrapscan)
  241.             {
  242.                 l = nlines + 1;
  243.                 wrapped = TRUE;
  244.                 continue;
  245.             }
  246.             else
  247.             {
  248.                 break;
  249.             }
  250.         }
  251.  
  252.         /* get this line */
  253.         line = fetchline(l);
  254.  
  255.         /* check this line */
  256.         if (regexec(re, line, 1) && (int)(re->startp[0] - line) < pos)
  257.         {
  258.             /* match!  now find the last acceptable one in this line */
  259.             do
  260.             {
  261.                 last = (int)(re->startp[0] - line);
  262.                 try = (int)(re->endp[0] - line);
  263.             } while (try > 0
  264.                  && regexec(re, &line[try], FALSE)
  265.                  && (int)(re->startp[0] - line) < pos);
  266.  
  267.             if (wrapped && *o_warn)
  268.                 msg("(wrapped)");
  269. #ifndef CRUNCH
  270.             if (delta != INFINITY)
  271.             {
  272.                 l += delta;
  273.                 if (l < 1 || l > nlines)
  274.                 {
  275.                     msg("search offset too big");
  276.                     return MARK_UNSET;
  277.                 }
  278.                 force_flags = LNMD|INCL;
  279.                 return MARK_AT_LINE(l);
  280.             }
  281. #endif
  282.             return MARK_AT_LINE(l) + last;
  283.         }
  284.         pos = BLKSIZE;
  285.     }
  286.  
  287.     /* not found */
  288.     msg(*o_wrapscan ? "Not found" : "Hit top without finding RE");
  289.     return MARK_UNSET;
  290. }
  291.  
  292.